'use strict';
const assert = require('assert');
const Controller = require('egg').Controller;

class UsersController extends Controller {
  get rules() {
    return {
      authorize: {
        scope        : /^openid$/,
        response_type: /^code$/,
        client_id    : /[0-9 a-z A-Z]{12}/,
        redirect_uri : /^http[s]?/,
        state        : 'string?',
      },
      token: {
        grant_type   : /^authorization_code$/,
        code         : /[0-9 a-z A-Z]{12}/,
        redirect_uri : /^http[s]?/,
        client_id    : 'string',
        client_secret: 'string',
      },
    };
  }
  /**
   * 解析 Authorization
   * @return {String} accessToken
   */
  resolveAuthorizationHeader() {
    const { ctx } = this;
    if (!ctx.header || !ctx.header.authorization) {
      return;
    }
    const parts = ctx.header.authorization.split(' ');
    if (parts.length === 2) {
      const scheme = parts[0];
      const credentials = parts[1];
      if (/^Bearer$/i.test(scheme)) {
        return credentials;
      }
    }
    // if (!opts.passthrough) {
    //     ctx.throw(401, 'Bad Authorization header format. Format is "Authorization: Bearer <token>"');
    // }
  }
  /**
   * 登录页
   * 已有登录信息则跳转到redirectUrl
   */
  async authorize() {
    const { ctx, rules, service } = this;
    let {
      scope, client_id, redirect_uri, state,
      // response_type 暂时没啥用
    } = ctx.helper.validate(rules.authorize, ctx.query);
    redirect_uri =  decodeURIComponent(redirect_uri);
    const code = await service.oidc.authorize(client_id, redirect_uri, scope);
    if (!code) {
      const url = await service.client.getUrlByClientId(client_id);
      ctx.logger.debug(`authorize-----: ${client_id},${redirect_uri},${url}`);
      await ctx.render('authorize', { client_id, redirect_uri, url });
      return;
    }
    const successUrl = `${redirect_uri}?code=${code}&state=${state}`;
    ctx.redirect(successUrl);
  }

  // /**
  //  * 验证登录状态
  //  */
  // async authenticate() {
  //   const { ctx } = this;
  //   ctx.body = {
  //     msg: 'successed!',
  //   };
  // }

  /**
   * 返回token信息
   */
  async token() {
    const { ctx, rules, service } = this;
    const {
      client_id, client_secret,
      code, redirect_uri,
      // grant_type
    } = ctx.helper.validate(rules.token, ctx.request.body);
    const {
      accessToken, refreshToken, expires, idToken,
    } = await service.oidc.token(code, redirect_uri, client_id, client_secret);
    ctx.body = {
      access_token : accessToken,
      refresh_token: refreshToken,
      expires_in   : expires,
      id_token     : idToken,
      tokenType    : 'Bearer',
    };
  }

  /**
   * 用户注册并记入登录信息
   */
  async register() {
    const { ctx, service } = this;
    const { name, password, lid, passwordConfirm, appId, redirectUri } = ctx.helper.validate({
      name           : 'string',
      lid            : 'string?',
      password       : 'string',
      passwordConfirm: 'string',
      appId          : 'string',
      redirectUri    : 'string',
    }, ctx.request.body);
    assert(password === passwordConfirm, '密码不一致');
    await service.oidc.register(name, password, lid, appId, redirectUri);
    ctx.body = { result: 0 };
  }
  /**
   * 验证用户密码
   */
  async checkPsw() {
    const { ctx, service } = this;
    const { lid, password, appId, redirectUri } = ctx.helper.validate({
      lid        : 'string',
      password   : 'string',
      appId      : 'string',
      redirectUri: 'string',
    }, ctx.request.body);
    await service.oidc.checkPsw(lid, password,  appId, redirectUri);
    ctx.body = { result: 0 };
  }

  /**
   * 登出
   */
  async logout() {
    const { ctx, service } = this;
    const { lid, accessToken, clientId } = ctx.helper.validate({
      lid        : 'string',
      accessToken: 'string',
      clientId   : 'string?',
    }, ctx.query);
    await service.oidc.logout(lid, accessToken, clientId);
    ctx.body = { result: 0 };
  }
}

module.exports = UsersController;
